001    /*
002     * Copyright 2003-2005 The Apache Software Foundation
003     * Copyright 2005 Stephen McConnell
004     *
005     * Licensed under the Apache License, Version 2.0 (the "License");
006     * you may not use this file except in compliance with the License.
007     * You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package net.dpml.cli.builder;
018    
019    import java.util.HashSet;
020    import java.util.Set;
021    
022    import net.dpml.cli.Argument;
023    import net.dpml.cli.Group;
024    import net.dpml.cli.option.DefaultOption;
025    import net.dpml.cli.resource.ResourceConstants;
026    import net.dpml.cli.resource.ResourceHelper;
027    
028    /**
029     * Builds DefaultOption instances.
030     *
031     * @author <a href="http://www.dpml.net">Digital Product Meta Library</a>
032     * @version 1.0.0
033     */
034    public class DefaultOptionBuilder
035    {
036        private final String m_shortPrefix;
037        private final String m_longPrefix;
038        private final boolean m_burstEnabled;
039        private String m_preferredName;
040        private Set m_aliases;
041        private Set m_burstAliases;
042        private boolean m_required;
043        private String m_description;
044        private Argument m_argument;
045        private Group m_children;
046        private int m_id;
047    
048        /**
049         * Creates a new DefaultOptionBuilder using defaults
050         * @see DefaultOption#DEFAULT_SHORT_PREFIX
051         * @see DefaultOption#DEFAULT_LONG_PREFIX
052         * @see DefaultOption#DEFAULT_BURST_ENABLED
053         */
054        public DefaultOptionBuilder()
055        {
056            this( 
057              DefaultOption.DEFAULT_SHORT_PREFIX, 
058              DefaultOption.DEFAULT_LONG_PREFIX,
059              DefaultOption.DEFAULT_BURST_ENABLED );
060        }
061    
062        /**
063         * Creates a new DefaultOptionBuilder
064         * @param shortPrefix the prefix to use for short options
065         * @param longPrefix the prefix to use for long options
066         * @param burstEnabled whether to allow gnu style bursting
067         * @throws IllegalArgumentException if either prefix is less than on
068         *                                  character long
069         */
070        public DefaultOptionBuilder( 
071          final String shortPrefix, final String longPrefix, final boolean burstEnabled )
072          throws IllegalArgumentException
073        {
074            if( ( shortPrefix == null ) || ( shortPrefix.length() == 0 ) )
075            {
076                throw new IllegalArgumentException(
077                  ResourceHelper.getResourceHelper().getMessage(
078                    ResourceConstants.OPTION_ILLEGAL_SHORT_PREFIX ) );
079            }
080    
081            if( ( longPrefix == null ) || ( longPrefix.length() == 0 ) )
082            {
083                throw new IllegalArgumentException(
084                  ResourceHelper.getResourceHelper().getMessage(
085                    ResourceConstants.OPTION_ILLEGAL_LONG_PREFIX ) );
086            }
087    
088            m_shortPrefix = shortPrefix;
089            m_longPrefix = longPrefix;
090            m_burstEnabled = burstEnabled;
091            reset();
092        }
093    
094        /**
095         * Creates a DefaultOption instance
096         * @return the new instance
097         * @throws IllegalStateException if no names have been supplied
098         */
099        public DefaultOption create() throws IllegalStateException
100        {
101            if( m_preferredName == null )
102            {
103                throw new IllegalStateException(
104                  ResourceHelper.getResourceHelper().getMessage(
105                    ResourceConstants.OPTION_NO_NAME ) );
106            }
107            final DefaultOption option =
108                new DefaultOption(
109                  m_shortPrefix, 
110                  m_longPrefix, 
111                  m_burstEnabled, 
112                  m_preferredName, 
113                  m_description,
114                  m_aliases, 
115                  m_burstAliases, 
116                  m_required, 
117                  m_argument, 
118                  m_children, 
119                  m_id );
120            reset();
121            return option;
122        }
123    
124        /**
125         * Resets the builder.
126         * @return this <code>DefaultOptionBuilder</code>.
127         */
128        public DefaultOptionBuilder reset()
129        {
130            m_preferredName = null;
131            m_description = null;
132            m_aliases = new HashSet();
133            m_burstAliases = new HashSet();
134            m_required = false;
135            m_argument = null;
136            m_children = null;
137            m_id = 0;
138            return this;
139        }
140    
141        /**
142         * Use this short option name. The first name is used as the preferred
143         * display name for the Command and then later names are used as aliases.
144         *
145         * @param shortName the name to use
146         * @return this builder
147         */
148        public DefaultOptionBuilder withShortName( final String shortName )
149        {
150            final String name = m_shortPrefix + shortName;
151            if( m_preferredName == null )
152            {
153                m_preferredName = name;
154            }
155            else
156            {
157                m_aliases.add( name );
158            }
159            if( m_burstEnabled && ( name.length() == ( m_shortPrefix.length() + 1 ) ) )
160            {
161                m_burstAliases.add( name );
162            }
163            return this;
164        }
165    
166        /**
167         * Use this long option name.  The first name is used as the preferred
168         * display name for the Command and then later names are used as aliases.
169         *
170         * @param longName the name to use
171         * @return this builder
172         */
173        public DefaultOptionBuilder withLongName( final String longName )
174        {
175            final String name = m_longPrefix + longName;
176            if( m_preferredName == null )
177            {
178                m_preferredName = name;
179            }
180            else
181            {
182                m_aliases.add( name );
183            }
184            return this;
185        }
186    
187        /**
188         * Use this option description
189         * @param newDescription the description to use
190         * @return this builder
191         */
192        public DefaultOptionBuilder withDescription( final String newDescription )
193        {
194            m_description = newDescription;
195            return this;
196        }
197    
198        /**
199         * Use this optionality
200         * @param newRequired true iff the Option is required
201         * @return this builder
202         */
203        public DefaultOptionBuilder withRequired( final boolean newRequired )
204        {
205            m_required = newRequired;
206            return this;
207        }
208    
209        /**
210         * Use this child Group
211         * @param newChildren the child Group to use
212         * @return this builder
213         */
214        public DefaultOptionBuilder withChildren( final Group newChildren )
215        {
216            m_children = newChildren;
217            return this;
218        }
219    
220        /**
221         * Use this Argument
222         * @param newArgument the argument to use
223         * @return this builder
224         */
225        public DefaultOptionBuilder withArgument( final Argument newArgument )
226        {
227            m_argument = newArgument;
228            return this;
229        }
230    
231        /**
232         * Sets the id
233         *
234         * @param newId
235         *            the id of the DefaultOption
236         * @return this DefaultOptionBuilder
237         */
238        public final DefaultOptionBuilder withId( final int newId )
239        {
240            m_id = newId;
241            return this;
242        }
243    }